﻿using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using Loong.Domain.Entities;
using Loong.Domain.Uow;
using Loong.Reflection;
using Loong.Runtime.Session;

namespace Loong.Dapper.Filters.Action
{
    public abstract class DapperActionFilterBase
    {
        private readonly ILoongSession _loongSession;
        private readonly IGuidGenerator _guidGenerator;
        private readonly ICurrentUnitOfWorkProvider _currentUnitOfWorkProvider;

        protected DapperActionFilterBase(
            ILoongSession loongSession,
            IGuidGenerator guidGenerator,
            ICurrentUnitOfWorkProvider currentUnitOfWorkProvider)
        {
            _loongSession = loongSession;
            _guidGenerator = guidGenerator;
            _currentUnitOfWorkProvider = currentUnitOfWorkProvider;
        }

        protected virtual long? GetAuditUserId()
        {
            if (_loongSession.UserId.HasValue && _currentUnitOfWorkProvider?.Current != null)
            {
                return _loongSession.UserId;
            }

            return null;
        }

        protected virtual void CheckAndSetId(object entityAsObj)
        {
            var entity = entityAsObj as IEntity<Guid>;
            if (entity != null && entity.Id == Guid.Empty)
            {
                Type entityType = entityAsObj.GetType();
                PropertyInfo idProperty = entityType.GetProperty("Id");
                var dbGeneratedAttr = ReflectionHelper.GetSingleAttributeOrDefault<DatabaseGeneratedAttribute>(idProperty);
                if (dbGeneratedAttr == null || dbGeneratedAttr.DatabaseGeneratedOption == DatabaseGeneratedOption.None)
                {
                    entity.Id = _guidGenerator.Create();
                }
            }
        }
    }
}
